/*
 *  Copyright 2008 The MITRE Corporation (http://www.mitre.org/). All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.mitre.mrald.util;

import java.sql.ResultSet;
import java.sql.SQLException;

/**
 *  This class is meant to serve as a base class for all messages in the MRALD
 *  system. These messages are generate by actions that the users perform that
 *  the administrator will need to know about.
 *
 *@author     tcornett
 *@created    August 31, 2004
 */
public class MraldMessage
{
    private static MraldConnection conn;
    public enum Status { NEW, READ, ARCHIVE, BROADCAST }

    /**
     *  Constructor for the MraldMessage object
     */
    public MraldMessage() {
        conn = new MraldConnection( MetaData.ADMIN_DB );
    }


    /**
     *  Creating and Deactivating a Message
     *
     *  These represent the only operations allowed
     *  on a message in the system.  The message will never be
     *  deleted as they are needed for auditing purposes.
     *
     *@param  title                       The feature to be added to the Message
     *      attribute
     *@param  body                        The feature to be added to the Message
     *      attribute
     *@return                             Description of the Return Value
     *@exception  ClassNotFoundException  Description of the Exception
     *@exception  SQLException            Description of the Exception
     *@exception  MraldException          Description of the Exception
     */
    public static boolean addMessage( String title, String body )
        throws ClassNotFoundException, MraldException, SQLException
    {
        //the message had an auto-sequence on the id - don't include it in the insert statement
        String insert = "INSERT INTO message (time_sent, title, body, status) values ('</time_sent/>', '" + title + "', '" + body + "' )";

        // ResultSet rs = conn.createStatement().executeQuery( "SELECT max(id) FROM message" );
        // rs.next();
        // int id = rs.getInt( 1 ) + 1;
        insert = MiscUtils.replace( insert, "</time_sent/>", java.util.Calendar.getInstance().getTime().toString() );
        conn.createStatement().executeUpdate( insert );
        return true;
    }


    /*
     *  Retrieval methods
     *
     *  Allow for the retrieval of a message and any of the vital pieces
     */
    /**
     *  Gets the message attribute of the MraldMessage class
     *
     *@param  ID                          Description of the Parameter
     *@return                             The message value
     *@exception  ClassNotFoundException  Description of the Exception
     *@exception  SQLException            Description of the Exception
     */
    public static String[] getMessage( int ID )
        throws ClassNotFoundException, SQLException
    {
        String query = "SELECT DISTINCT id, title, body FROM message WHERE id = " + ID;

        ResultSet rs = conn.createStatement().executeQuery( query );
        rs.next();
        String[] toReturn = {rs.getString( "id" ), rs.getString( "title" ), rs.getString( "body" )};
        return toReturn;
    }


    /**
     *  Gets the title attribute of the MraldMessage class
     *
     *@param  ID                          Description of the Parameter
     *@return                             The title value
     *@exception  ClassNotFoundException  Description of the Exception
     *@exception  SQLException            Description of the Exception
     */
    public static String getTitle( int ID )
        throws ClassNotFoundException, SQLException
    {
        String query = "SELECT DISTINCT title FROM message WHERE id = " + ID;

        ResultSet rs = conn.createStatement().executeQuery( query );
        rs.next();
        String toReturn = rs.getString( "title" );
        return toReturn;
    }


    /**
     *  Gets the body attribute of the MraldMessage class
     *
     *@param  ID                          Description of the Parameter
     *@return                             The body value
     *@exception  ClassNotFoundException  Description of the Exception
     *@exception  SQLException            Description of the Exception
     */
    public static String getBody( int ID )
        throws ClassNotFoundException, SQLException
    {
        String query = "SELECT DISTINCT body FROM message WHERE id = " + ID;

        ResultSet rs = conn.createStatement().executeQuery( query );
        rs.next();
        String toReturn = rs.getString( "body" );
        return toReturn;
    }


    /*
     *  Set as Read or New
     */
    /**
     *  Sets the asRead attribute of the MraldMessage class
     *
     *@param  ID                          The new asRead value
     *@return                             Description of the Return Value
     *@exception  ClassNotFoundException  Description of the Exception
     *@exception  SQLException            Description of the Exception
     */
    protected static boolean setAsRead( String ID )
        throws ClassNotFoundException, SQLException
    {
        String query = "UPDATE message SET status = 'READ' WHERE id = " + ID;

        conn.createStatement().executeUpdate( query );
        return true;
    }


    /**
     *  Sets the asRead attribute of the MraldMessage class
     *
     *@param  IDs                         The new asRead value
     *@return                             Description of the Return Value
     *@exception  ClassNotFoundException  Description of the Exception
     *@exception  SQLException            Description of the Exception
     */
    public static boolean setAsRead( String[] IDs )
        throws ClassNotFoundException, SQLException
    {
        for ( int i = 0; i < IDs.length; i++ )
        {
            setAsRead( IDs[i] );
        }
        return true;
    }


    /**
     *  Sets the asNew attribute of the MraldMessage class
     *
     *@param  ID                          The new asNew value
     *@return                             Description of the Return Value
     *@exception  ClassNotFoundException  Description of the Exception
     *@exception  SQLException            Description of the Exception
     */
    protected static boolean setAsNew( String ID )
        throws ClassNotFoundException, SQLException
    {
        String query = "UPDATE message SET status = 'NEW' WHERE id = " + ID;

        conn.createStatement().executeUpdate( query );
        return true;
    }


    /**
     *  Sets the asNew attribute of the MraldMessage class
     *
     *@param  IDs                         The new asNew value
     *@return                             Description of the Return Value
     *@exception  ClassNotFoundException  Description of the Exception
     *@exception  SQLException            Description of the Exception
     */
    public static boolean setAsNew( String[] IDs )
        throws ClassNotFoundException, SQLException
    {
        for ( int i = 0; i < IDs.length; i++ )
        {
            setAsNew( IDs[i] );
        }
        return true;
    }


    /**
     *  Set as Archive (read as Deleted) or Current
     *
     *@param  ID                          The new asArchive value
     *@return                             Description of the Return Value
     *@exception  ClassNotFoundException  Description of the Exception
     *@exception  SQLException            Description of the Exception
     */
    protected static boolean setAsArchive( String ID )
        throws ClassNotFoundException, SQLException
    {
        String query = "UPDATE message SET status = 'ARCHIVE' WHERE id = " + ID;

        conn.createStatement().executeUpdate( query );
        return true;
    }


    /**
     *  Sets the asArchive attribute of the MraldMessage class
     *
     *@param  IDs                         The new asArchive value
     *@return                             Description of the Return Value
     *@exception  ClassNotFoundException  Description of the Exception
     *@exception  SQLException            Description of the Exception
     */
    public static boolean setAsArchive( String[] IDs )
        throws ClassNotFoundException, SQLException
    {
        for ( int i = 0; i < IDs.length; i++ )
        {
            setAsArchive( IDs[i] );
        }
        return true;
    }


    /**
     *  Sets the asBroadcast attribute of the MraldMessage class
     *
     *@param  ID                          The new asBroadcast value
     *@return                             Description of the Return Value
     *@exception  ClassNotFoundException  Description of the Exception
     *@exception  SQLException            Description of the Exception
     */
    protected static boolean setAsBroadcast( String ID )
        throws ClassNotFoundException, SQLException
    {
        String query = "UPDATE message SET status = 'BROADCAST' WHERE id = " + ID;

        conn.createStatement().executeUpdate( query );
        return true;
    }


    /**
     *  Sets the asBroadcast attribute of the MraldMessage class
     *
     *@param  IDs                         The new asBroadcast value
     *@return                             Description of the Return Value
     *@exception  ClassNotFoundException  Description of the Exception
     *@exception  SQLException            Description of the Exception
     */
    public static boolean setAsBroadcast( String[] IDs )
        throws ClassNotFoundException, SQLException
    {
        for ( int i = 0; i < IDs.length; i++ )
        {
            setAsBroadcast( IDs[i] );
        }
        return true;
    }


    /*
     *  Misc Utilties
     *
     *  These are the utilites that can be used to get realtively
     *  important information.
     */
    /**
     *  Gets the newCount attribute of the MraldMessage class
     *
     *@return                             The newCount value
     *@exception  ClassNotFoundException  Description of the Exception
     *@exception  SQLException            Description of the Exception
     */
    public static int getNewCount()
        throws ClassNotFoundException, SQLException
    {
        String query = "SELECT DISTINCT Count(*) AS new_count FROM message WHERE message.status = 'NEW'";

        ResultSet rs = conn.createStatement().executeQuery( query );
        rs.next();
        int toReturn = rs.getInt( "new_count" );
        return toReturn;
    }


    /**
     *  Gets the totalCount attribute of the MraldMessage class - total number
     *  of new and read messages. Messages that are archived are not counted.
     *
     *@return                             The totalCount value
     *@exception  ClassNotFoundException  Description of the Exception
     *@exception  SQLException            Description of the Exception
     */
    public static int getTotalCount()
        throws ClassNotFoundException, SQLException
    {
        String query = "SELECT DISTINCT Count(*) AS total_count FROM message WHERE message.status = 'NEW' OR message.status = 'READ'";

        ResultSet rs = conn.createStatement().executeQuery( query );
        rs.next();
        int toReturn = rs.getInt( "total_count" );
        return toReturn;
    }
}

